/*
 *   Copyright 2012-present OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

// Packages
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import {
  Button,
  Classes,
  FormGroup,
  Intent,
  Position
} from '@blueprintjs/core';
import { Form, Validation } from 'calidation';
import AceEditor from 'react-ace';
import 'brace/mode/mysql';
import 'brace/theme/xcode';

// Services
import { ConnectionService } from '../../../../../../../services';

// Utils
import { Saiku } from '../../../../../../../utils';

// Constants
const ADVANCED_TEMPLATE = `type=OLAP
name=null
driver=null
location=null
username=null
password=null
security.enabled=false
`;

class AdvancedForm extends Component {
  constructor(props) {
    super(props);

    this.state = {
      initialValues: {
        advanced: ADVANCED_TEMPLATE
      },
      loading: false
    };

    this.formValidationConfig = {
      advanced: {
        isRequired: 'Advanced field is required'
      }
    };
  }

  componentWillMount() {
    const { editMode, dataSourceData } = this.props;

    if (editMode) {
      const { advanced } = dataSourceData;

      this.setState({
        initialValues: {
          advanced: advanced === null ? '' : advanced
        }
      });
    }
  }

  handleSubmit = ({ fields, errors, isValid }) => {
    if (isValid) {
      const { editMode, dataSourceData, getDataSources, onClose } = this.props;
      const { advanced } = fields;
      let data = {};

      this.setState({ loading: true });

      if (!editMode) {
        data = {
          advanced
        };

        ConnectionService.addDataSource(data)
          .then(res => {
            this.setState({ loading: false });

            if (res.status === 200) {
              Saiku.toasts(Position.TOP_RIGHT).show({
                icon: 'tick',
                intent: Intent.SUCCESS,
                message: 'Data source added'
              });

              getDataSources();
              onClose();
            } else {
              Saiku.toasts(Position.TOP_RIGHT).show({
                icon: 'error',
                intent: Intent.DANGER,
                message: res.statusText
              });
            }
          })
          .catch(error => {
            Saiku.toasts(Position.TOP_RIGHT).show({
              icon: 'error',
              intent: Intent.DANGER,
              message: 'Something went wrong'
            });
          });
      } else {
        const { id } = dataSourceData;
        data = {
          advanced
        };

        ConnectionService.updateDataSource(id, data)
          .then(res => {
            this.setState({ loading: false });

            if (res.status === 200) {
              Saiku.toasts(Position.TOP_RIGHT).show({
                icon: 'tick',
                intent: Intent.SUCCESS,
                message: 'Data source updated'
              });

              getDataSources();
              onClose();
            } else {
              Saiku.toasts(Position.TOP_RIGHT).show({
                icon: 'error',
                intent: Intent.DANGER,
                message: res.statusText
              });
            }
          })
          .catch(error => {
            Saiku.toasts(Position.TOP_RIGHT).show({
              icon: 'error',
              intent: Intent.DANGER,
              message: 'Something went wrong'
            });
          });
      }
    }
  };

  renderForm() {
    const { editMode, connType, onClose } = this.props;
    const { initialValues, loading } = this.state;

    return (
      <Form onSubmit={this.handleSubmit} style={{ margin: 0 }}>
        <Validation
          config={this.formValidationConfig}
          initialValues={initialValues}
        >
          {({ fields, errors, submitted, setField }) => (
            <Fragment>
              <div className={Classes.DIALOG_BODY}>
                <FormGroup
                  label="Advanced Mode"
                  labelFor="advanced"
                  intent={
                    submitted && errors.advanced ? Intent.DANGER : Intent.NONE
                  }
                  helperText={
                    submitted && errors.advanced ? errors.advanced : ''
                  }
                >
                  <AceEditor
                    name="advanced"
                    mode="mysql"
                    theme="xcode"
                    fontSize={14}
                    showPrintMargin={true}
                    showGutter={true}
                    highlightActiveLine={true}
                    height="400px"
                    width="auto"
                    editorProps={{ $blockScrolling: true }}
                    value={fields.advanced}
                    setOptions={{
                      showLineNumbers: true,
                      tabSize: 2
                    }}
                    onChange={value => setField({ advanced: value })}
                  />
                </FormGroup>
              </div>
              <div className={Classes.DIALOG_FOOTER}>
                <div className={Classes.DIALOG_FOOTER_ACTIONS}>
                  <Button text="← Back" onClick={() => connType('MONDRIAN')} />
                  <Button
                    type="submit"
                    text={!editMode ? 'Add' : 'Save'}
                    intent={Intent.DANGER}
                    loading={loading}
                  />
                  <Button text="Close" onClick={onClose} />
                </div>
              </div>
            </Fragment>
          )}
        </Validation>
      </Form>
    );
  }

  render() {
    return this.renderForm();
  }
}

AdvancedForm.propTypes = {
  editMode: PropTypes.bool,
  connType: PropTypes.func,
  getDataSources: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired
};

AdvancedForm.defaultProps = {
  editMode: false
};

export default AdvancedForm;
